import numpy as np
A = np.array([1,2])
B = np.array([4,5])
print(A + B) # array([5,7])
print(A * B) # array([4,10])
print(A ** 2) # array([1,4])
print(A + 2) # array([3,4])
10*np.sin(A) # 각 요소에 sin() 적용; array( [8.41470985,9.09297427] )
A<3 # array([ True,True ], dtype=bool)
A *= B # A = A*B와 동일; B와 곱한 다음에 A에 저장; array( [4,10] )
A[0:2,] # array( [4,10] )
NumPy는 수학 함수 np.sin()
, np.cos()
등을 제공한다.
스칼라값을 입력으로 하는 math 패키지와 달리 배열에 대해 elementwise로(즉, 각 요소에 대해) 적용된다.
import numpy as np
x = np.arange(0.,np.pi,1.) # array( [0.,1.,2.,3.] )
y = np.sin(x) # array( [0., 0.84147098, 0.90929743, 0.14112001] )
import numpy as np
A = np.arange(4).reshape(2,2) # (2,2); array( [[0,1],[2,3]] )
B = np.arange(5,5+4).reshape(2,2) # (2,2); array( [[5,6],[7,8]] )
X = np.arange(2) # (2,); array( [0,1] )
Y = np.arange(2).reshape(2,1) # (2,1); array( [[0],[1]] )
Z = np.arange(2).reshape(1,2) # (1,2); array( [[0,1]] )
# A*B, (2,2)*(2*2) = (2,2), 같은 결과
C1 = np.dot(A,B) # array( [[7,8],[31,36]] )
C2 = np.matmul(A,B) # array( [[7,8],[31,36]] )
C3 = A@B # array( [[7,8],[31,36]] )
# A*X, (2,2)*(1*2) = (1,2), 같은 결과
AX1 = np.dot(A,X) # array( [1,3] )
AX2 = np.matmul(A,X) # array( [1,3] )
AX3 = A@X # array( [1,3] )
# A*Y, (2,2)*(2*1) = (2,1), 같은 결과
AY1 = np.dot(A,Y) # array( [[1],[3]] )
AY2 = np.matmul(A,Y) # array( [[1],[3]] )
AY3 = A@Y # array( [[1],[3]] )
# A*Z, (2,2)*(1*2) = (1,2), 행렬 차수 에러
AZ1 = np.dot(A,Z)
AZ2 = np.matmul(A,Z)
AZ3 = A@Z
# X*Y, (1,2)*(2*1) = (1,2)
XY = X@Y # array([1])
#전치행렬(transpose matrix)
A.T # array( [[0, 2],[1, 3]] )
np.transpose(A) # array( [[0, 2],[1, 3]] )
# 선형대수함수
A = np.array( [[1,2],[3,7]] )
[D,V] = np.linalg.eig(A) # D = eigenvalues, V = eigen vectors
#언팩킹(unpacking): *(asterisk)를 사용
np.array([0,60,40,20,0,np.zeros(n-5)]) --> array([0, 60, 40, 20, 0, array([0., 0., 0., ..., 0., 0., 0.])], dtype=object)
np.array([0,60,40,20,0,*np.zeros(n-5)]) --> array([ 0., 60., 40., ..., 0., 0., 0.])
import numpy as np
X = np.array( [9.1,8.2,2.3] )
np.amin(X) # 최솟값, 2.3
np.amax(X) # 최댓값, 9.1
np.argmin(X) # 최솟값 위치, 2
np.argmax(X) # 최댓값 위치, 0
np.sort(X) # 오름차순 정렬, array( [2.3,8.2,9.1] )
np.argsort(X) # 오름차순 정렬 위치, array([2, 1, 0], dtype=int64)
np.argsort(X)[0] # 가장 작은 값의 위치, 2
np.argsort(X)[-1] # 가장 큰 값의 위치, 0
np.argsort(X)[-2] # 두 번째로 큰 값의 위치, 1
형태가 다른 행렬의 연산
import numpy as np
A = np.arange(4.).reshape(2,2) # 2D array, (2,2), array( [[0.,1.],[2.,3.]] )
X = np.array( [1.,0.] ) # 1D array, (2,) , array( [1.,0.] )
Y = X.reshape(1,2) # 2D array, (1,2), array( [[1.,0.]] )
Z = X.reshape(2,1) # 2D array, (2,1), array( [[1.],[0.]] )
A+1 # (2,2) + scalar*I = (2,2); array( [[1.,2.],[3.,4.]] )
A+X # (2,2) + (2,) = (2,2); array( [[1.,1.], [3.,3.]])
A+Y # (2,2) + (1,2) = (2,2); array( [[1.,1.], [3.,3.]])
A+Z # (2,2) + (2,1) = (2,2); array( [[1.,2.], [2.,3.]])
행렬 연산 함수 호출시 주의사항
import numpy as np
A = np.arange(4.).reshape(2,2) # 2D array, (2,2), array( [[0.,1.],[2.,3.]] )
X = np.array( [1.,0.] ) # 1D array, (2,)
Y = X.reshape(1,2) # 2D array, (1,2)
Z = X.reshape(2,1) # 2D array, (2,1)
np.matmul(A,Y) # (2,2)*(1,2) = Dimension Error
np.matmul(A,Z) # (2,2)*(2,1) = (2,1), array( [[0.],[2.]] )
np.matmul(A,X) # (2,2)*(2,) = (2,), array( [0.,2.] )
깊은 복사(deep copy): 서로 값만 같을 뿐 본질적으로 서로 다르기 때문에 한 변수가 수정될 시 다른 변수가 수정되지 않는다.
얕은 복사(shallow copy): 서로 다른 변수명이지만 본질적으로 서로 같은 대상을 의미하므로 하나의 변수 역시 수정이 된다.
import numpy as np
A = [1,2,3] # [1, 2, 3]
X = np.array(A) # array( [1, 2, 3] )
Z = X.copy() # deep copy
Z is X # False
Y = X # shallow copy
Y[0] = 10 #
X # array( [10, 2, 3] )
Y # array( [10, 2, 3] )
Y is X # True
X is Y # True
부분행렬은 얕은 복사이다.
import numpy as np
X = np.array( [1,2,3] )
Y = X[0:2] # shallow copy
Y[0] = 10 #
Y # array( [10,2] )
X # array( [10,2,3] )